The tasks included in this report are:

unique(measure_labels$task_group)
 [1] "adaptive_n_back"             "attention_network_task"     
 [3] "choice_reaction_time"        "directed_forgetting"        
 [5] "dot_pattern_expectancy"      "local_global_letter"        
 [7] "motor_selective_stop_signal" "recent_probes"              
 [9] "shape_matching"              "simon"                      
[11] "stim_selective_stop_signal"  "stop_signal"                
[13] "stroop"                      "threebytwo"                 
adaptive_n_back

attention_network_task

choice_reaction_time

directed_forgetting

dot_pattern_expectancy

local_global_letter

motor_selective_stop_signal

recent_probes

shape_matching

simon

stim_selective_stop_signal

stop_signal

stroop

threebytwo

Our analyses span 512 different measures.

NOTE: We found that HDDM parameters for T1 data do not differ in any detectable way depending on whether they are fit using the full T1 sample (n=522) or only for the subset who completed the T2 battery as well (n=150). Therefore the T1 HDDM parameters in this report are based on fits from n=150. Details of these analyses can be found here.

DDM vs raw reliability overall

Plot reliability point estimates comparing DDM measures to raw measures faceting for contrast measures.

fig_name = 'ddmvsraw_point.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

Plot averaged bootstrapped reliability estimates per measure comparing DDM measures to raw measures faceting for contrast measures.

fig_name = 'ddmvsraw_boot.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

Model testing if the reliability of raw measures differs from that of ddm estimates and if contrast measures differ from non-contrast measures.

Checking if both fixed effects of raw vs ddm and contrast vs non-contrast as well as their interaction is necessary.

Conclusion: Interactive model is best.

mer1 = lmer(icc2.1 ~ ddm_raw + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer1a = lmer(icc2.1 ~ overall_difference + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer2 = lmer(icc2.1 ~ ddm_raw + overall_difference + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer3 = lmer(icc2.1 ~ ddm_raw * overall_difference + (1|dv), boot_df %>% filter(rt_acc != "other"))
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
anova(mer1, mer2, mer3)
refitting model(s) with ML (instead of REML)
anova(mer1a, mer2, mer3)
refitting model(s) with ML (instead of REML)
rm(mer1, mer2, mer1a)

Raw measures do not significantly differ from ddm parameters in their reliability but non-contrast measures are significantly more reliable compared to contrast and condition measures.

summary(mer3)
Linear mixed model fit by REML ['lmerMod']
Formula: icc2.1 ~ ddm_raw * overall_difference + (1 | dv)
   Data: boot_df %>% filter(rt_acc != "other")

REML criterion at convergence: -546356

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-5.537 -0.630  0.014  0.643  6.045 

Random effects:
 Groups   Name        Variance Std.Dev.
 dv       (Intercept) 0.01841  0.1357  
 Residual             0.00751  0.0866  
Number of obs: 267000, groups:  dv, 267

Fixed effects:
                                      Estimate Std. Error t value
(Intercept)                             0.3681     0.0146   25.16
ddm_rawraw                              0.0837     0.0288    2.91
overall_differencecontrast             -0.2384     0.0218  -10.91
overall_differencecondition            -0.0919     0.0323   -2.85
ddm_rawraw:overall_differencecontrast  -0.0564     0.0397   -1.42

Correlation of Fixed Effects:
                (Intr) ddm_rw ovrll_dffrnccnt ovrll_dffrnccnd
ddm_rawraw      -0.509                                       
ovrll_dffrnccnt -0.670  0.341                                
ovrll_dffrnccnd  0.000 -0.661  0.000                         
ddm_rwrw:v_      0.369 -0.725 -0.550           0.479         
fit warnings:
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient

Best measure for each task

What is the best measure of individual difference for any measure that has both raw and DDM parameters?

Even though overall the ddm parameters are not significantly less reliable the most reliable measure is more frequently a raw measure. There are some examples of an EZ estimate being the best for a task as well. Regardless of raw vs ddm the best measure is always a non-contrast measure.

rel_df %>%
  group_by(task_group) %>%
  filter(icc2.1 == max(icc2.1)) %>%
  select(task_group, everything())

Variance breakdown measure types

fig_name = 'ddmvsraw_varsubs.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

fig_name = 'ddmvsraw_varresid.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

Model testing if the percentage of between subjects variance of raw measures differs from that of ddm estimates and if contrast measures differ from non-contrast measures.

Checking if both fixed effects of raw vs ddm and contrast vs non-contrast as well as their interaction is necessary.

Conclusion: Model with fixed effects for both is best.

mer1 = lmer(var_subs_pct ~ ddm_raw + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer1a = lmer(var_subs_pct ~ overall_difference + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer2 = lmer(var_subs_pct ~ ddm_raw +  overall_difference + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer3 = lmer(var_subs_pct ~ ddm_raw *  overall_difference + (1|dv), boot_df %>% filter(rt_acc != "other"))
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
anova(mer1, mer2, mer3)
refitting model(s) with ML (instead of REML)
anova(mer1a, mer2, mer3)
refitting model(s) with ML (instead of REML)
rm(mer1, mer1a, mer3)

Contrast measures have lower between subjects variability (ie are worse individual difference measures). Raw and ddm measures do not differ significantly.

summary(mer2)
Linear mixed model fit by REML ['lmerMod']
Formula: var_subs_pct ~ ddm_raw + overall_difference + (1 | dv)
   Data: boot_df %>% filter(rt_acc != "other")

REML criterion at convergence: 2173929

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-3.648 -0.725  0.020  0.758  4.603 

Random effects:
 Groups   Name        Variance Std.Dev.
 dv       (Intercept) 142      11.9    
 Residual             200      14.1    
Number of obs: 267000, groups:  dv, 267

Fixed effects:
                            Estimate Std. Error t value
(Intercept)                    42.30       1.20   35.40
ddm_rawraw                      4.15       1.74    2.38
overall_differencecontrast     -6.44       1.60   -4.02
overall_differencecondition     0.53       2.49    0.21

Correlation of Fixed Effects:
                (Intr) ddm_rw ovrll_dffrnccnt
ddm_rawraw      -0.377                       
ovrll_dffrnccnt -0.602 -0.101                
ovrll_dffrnccnd -0.216 -0.519  0.360         

Model testing if the percentage of residual variance of raw measures differs from that of ddm estimates and if contrast measures differ from non-contrast measures.

Checking if both fixed effects of raw vs ddm and contrast vs non-contrast as well as their interaction is necessary.

Conclusion: Interactive model is best

mer1 = lmer(var_resid_pct ~ ddm_raw + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer1a = lmer(var_resid_pct ~ overall_difference + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer2 = lmer(var_resid_pct ~ ddm_raw + overall_difference + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer3 = lmer(var_resid_pct ~ ddm_raw * overall_difference + (1|dv), boot_df %>% filter(rt_acc != "other"))
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
anova(mer1, mer2, mer3)
refitting model(s) with ML (instead of REML)
anova(mer1a, mer2, mer3)
refitting model(s) with ML (instead of REML)
rm(mer1, mer1a, mer2)

Both contrast and condition measures have higher residual variance. Raw and ddm measures do not differ.

summary(mer3)
Linear mixed model fit by REML ['lmerMod']
Formula: var_resid_pct ~ ddm_raw * overall_difference + (1 | dv)
   Data: boot_df %>% filter(rt_acc != "other")

REML criterion at convergence: 1907553

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-4.042 -0.640 -0.018  0.658  4.753 

Random effects:
 Groups   Name        Variance Std.Dev.
 dv       (Intercept) 49.6     7.04    
 Residual             73.7     8.59    
Number of obs: 267000, groups:  dv, 267

Fixed effects:
                                      Estimate Std. Error t value
(Intercept)                             18.746      0.760   24.67
ddm_rawraw                              -0.973      1.494   -0.65
overall_differencecontrast               9.462      1.134    8.34
overall_differencecondition              3.885      1.676    2.32
ddm_rawraw:overall_differencecontrast    0.501      2.061    0.24

Correlation of Fixed Effects:
                (Intr) ddm_rw ovrll_dffrnccnt ovrll_dffrnccnd
ddm_rawraw      -0.509                                       
ovrll_dffrnccnt -0.670  0.341                                
ovrll_dffrnccnd  0.000 -0.661  0.000                         
ddm_rwrw:v_      0.369 -0.725 -0.550           0.479         
fit warnings:
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
rm(mer3)

Effects of sample size on reliability can be found here.

Hierarchical estimation consequences

The H in HDDM estimates stands for ‘hierarchical’ denoting the fact that the distribution of the whole sample is incorportated in the priors for the model parameters. This is different than e.g. EZ-diffusion parameters that would be the same for a given subject’s data regardless of the rest of the sample. One can ask whether this H indeed has a measurable impact.

HDDM and EZ parameter estimates might differ due to other difference in the estimation process as well. Therefore to evaluate whether the ‘H’ leads to meaningful changes in parameters we compare the same models fit on the same data using either the whole sample for the hierarchical structure or only the single subject’s data. These latter estimates are referred to as ‘flat’ estimates.

retest_hddm_flat = read.csv(paste0(retest_data_path,'retest_hddm_flat.csv'))

retest_hddm_flat = retest_hddm_flat %>% rename(sub_id = subj_id)

test_hddm_flat = read.csv(paste0(retest_data_path,'/t1_data/t1_hddm_flat.csv'))

test_hddm_flat = test_hddm_flat %>% rename(sub_id = subj_id)

# numeric_cols = get_numeric_cols()

# Check if all the variables are there (no for now)
# sum(names(retest_hddm_flat) %in% numeric_cols) == length(names(retest_hddm_flat))
# names(retest_hddm_flat)[which(names(retest_hddm_flat) %in% numeric_cols == FALSE)]

# sum(names(test_hddm_flat) %in% numeric_cols) == length(names(test_hddm_flat))
# names(test_hddm_flat)[which(names(test_hddm_flat) %in% numeric_cols == FALSE)]

Parameter value

Plot percent change in raw parameters for retest and t1 for each of 3 parameters (using hierarchical as baseline: what percent does the flat parameter change compared to the hierarchical)

For both time points the thresholds and non-decision times are very similary regardless of whether they are estimated heirarchically or without the hierarchy (difference peaking at 0).

This is also true for the majority of the drift rates. There are, however, almost as many drift rates that change completely when estimated without the hierarchy.

#Should not be necessary later
common_cols = names(retest_hddm_flat)[names(retest_hddm_flat) %in% names(retest_data)]
common_cols=common_cols[common_cols %in% names(test_hddm_flat)]

retest_hddm_hier = retest_data %>% select(common_cols) %>% mutate(hddm="hierarchical")
test_hddm_hier = test_data %>% select(common_cols)  %>% mutate(hddm="hierarchical")
retest_hddm_flat = retest_hddm_flat %>% select(common_cols) %>% mutate(hddm="flat")
test_hddm_flat = test_hddm_flat %>% select(common_cols) %>% mutate(hddm="flat")

retest_flat_difference = rbind(retest_hddm_hier, retest_hddm_flat)
retest_flat_difference = retest_flat_difference %>%
  gather(dv, value, -sub_id, -hddm) %>%
  spread(hddm, value) %>%
  mutate(diff_pct = (hierarchical - flat)/hierarchical*100,
         diff_pct = ifelse(diff_pct<(-100), -100, ifelse(diff_pct>100, 100, diff_pct)),
         time = "retest",
         par = ifelse(grepl("drift", dv), "drift", ifelse(grepl("thresh", dv), "thresh", ifelse(grepl("non_decision", dv), "non_decision", NA))))

test_flat_difference = rbind(test_hddm_hier, test_hddm_flat)
test_flat_difference = test_flat_difference %>%
  gather(dv, value, -sub_id, -hddm) %>%
  spread(hddm, value) %>%
  mutate(diff_pct = (hierarchical - flat)/hierarchical*100,
         diff_pct = ifelse(diff_pct<(-100), -100, ifelse(diff_pct>100, 100, diff_pct)),
         time = "test",
         par = ifelse(grepl("drift", dv), "drift", ifelse(grepl("thresh", dv), "thresh", ifelse(grepl("non_decision", dv), "non_decision", NA))))

flat_difference = rbind(test_flat_difference, retest_flat_difference)
flat_difference %>%
  ggplot(aes(diff_pct))+
  geom_histogram()+
  facet_grid(factor(time, levels = c("test", "retest"),labels = c("test", "retest")) ~ par, scales="free")+
  xlab("Percent change")
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Warning: Removed 1022 rows containing non-finite values (stat_bin).

Is the average percentage change different than 0? No.

This model uses the distribution of percentage difference in parameter estimates for drift rates as the baseline. A more appropriate model would test whether all three distributions are different than 0. The conclusion should not change: The intercept suggests that the mean of the drift rate difference distribution is at 0 and this is not different than the distributions for either of the other parameters and either time point.

summary(lmer(diff_pct ~ time*par+(1|dv), flat_difference %>% mutate(pars = factor(par, levels = c("thresh", "drift", "non_decision")))))
Linear mixed model fit by REML ['lmerMod']
Formula: diff_pct ~ time * par + (1 | dv)
   Data: 
flat_difference %>% mutate(pars = factor(par, levels = c("thresh",  
    "drift", "non_decision")))

REML criterion at convergence: 238677

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-3.244 -0.258 -0.016  0.213  3.853 

Random effects:
 Groups   Name        Variance Std.Dev.
 dv       (Intercept)  130     11.4    
 Residual             1443     38.0    
Number of obs: 23578, groups:  dv, 82

Fixed effects:
                         Estimate Std. Error t value
(Intercept)                 -1.19       1.64   -0.73
timetest                     1.64       0.62    2.65
parnon_decision              1.65       3.57    0.46
parthresh                   -1.84       3.39   -0.54
timetest:parnon_decision    -1.38       1.35   -1.02
timetest:parthresh          -1.71       1.28   -1.33

Correlation of Fixed Effects:
            (Intr) timtst prnn_d prthrs tmts:_
timetest    -0.191                            
parnon_dcsn -0.460  0.088                     
parthresh   -0.485  0.093  0.223              
tmtst:prnn_  0.088 -0.459 -0.191 -0.043       
tmtst:prthr  0.092 -0.483 -0.042 -0.192  0.222

Do people change in the same way? Mostly.

Plotting the raw parameter estimate that is estimated hierarchically against the estimate that is estimated without the hierarchy. Red lines are the 45-degree line. The fact that many points cluster around this line and that there are no systematic deviances from it for any parameter at either time point suggests that the hierarchical and flat estimates are mostly the same.

fig_name = 'HDDM_par_flatvshier.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

Parameter reliability

Plotting the reliability estimates for flat parameters against the reliability of hierarchical estimates. Red lines are 45-degree lines. While there are some changes in reliability nothing appears very large (or consequential in pushing the reliability to any acceptable level depending on the estimation method) or systematic.

rel_df_flat = make_rel_df(t1_df = test_hddm_flat, t2_df = retest_hddm_flat, metrics = c('icc2.1', 'pearson', 'var_breakdown'))

rel_df_flat = rel_df_flat %>%
  left_join(rel_df[,c("dv", "icc2.1", "rt_acc", "overall_difference")], by = "dv") 
fig_name = 'HDDM_rel_flatvshier.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

with(rel_df_flat %>% filter(rt_acc == "drift rate"), t.test(icc2.1.x, icc2.1.y, paired=T))

    Paired t-test

data:  icc2.1.x and icc2.1.y
t = 0.9, df = 51, p-value = 0.4
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.01310  0.03422
sample estimates:
mean of the differences 
                0.01056 
with(rel_df_flat %>% filter(rt_acc == "threshold"), t.test(icc2.1.x, icc2.1.y, paired=T))

    Paired t-test

data:  icc2.1.x and icc2.1.y
t = -1.9, df = 15, p-value = 0.07
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.073416  0.003664
sample estimates:
mean of the differences 
               -0.03488 
with(rel_df_flat %>% filter(rt_acc == "non-decision"), t.test(icc2.1.x, icc2.1.y, paired=T))

    Paired t-test

data:  icc2.1.x and icc2.1.y
t = -0.39, df = 13, p-value = 0.7
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.04242  0.02946
sample estimates:
mean of the differences 
              -0.006479 
rm(flat_difference, rel_df_flat, retest_flat_difference, retest_hddm_flat, retest_hddm_hier, test_flat_difference,  test_hddm_flat, test_hddm_hier)

Parameter fit

Do the fit statistics differ by whether the model was hierarchical or not? No.

t1_hierarchical_fitstats = t1_hierarchical_fitstats %>%
  filter(subj_id %in% retest_hierarchical_fitstats$subj_id)

tmp = rbind(retest_hierarchical_fitstats, retest_flat_fitstats, t1_hierarchical_fitstats, t1_flat_fitstats) %>%
  select(m_kl, subj_id, task_name, sample) %>%
  separate(sample, c("time", "proc"), sep="_", remove=FALSE)
Warning in `[<-.factor`(`*tmp*`, ri, value = c(5L, 7L, 9L, 11L, 12L, 14L, :
invalid factor level, NA generated

Warning in `[<-.factor`(`*tmp*`, ri, value = c(5L, 7L, 9L, 11L, 12L, 14L, :
invalid factor level, NA generated
fig_name = 'HDDM_fitstats_flatvshier.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

tmp
summary(lmer(m_kl ~ time*proc+(1|task_name),tmp))
Linear mixed model fit by REML ['lmerMod']
Formula: m_kl ~ time * proc + (1 | task_name)
   Data: tmp

REML criterion at convergence: 30849

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-2.058 -0.429 -0.199  0.163 13.706 

Random effects:
 Groups    Name        Variance Std.Dev.
 task_name (Intercept) 1.11     1.05    
 Residual              2.55     1.60    
Number of obs: 8147, groups:  task_name, 14

Fixed effects:
                        Estimate Std. Error t value
(Intercept)               1.4481     0.2834    5.11
timet1                    0.0487     0.0494    0.99
prochierarchical         -0.1476     0.0498   -2.96
timet1:prochierarchical  -0.0115     0.0710   -0.16

Correlation of Fixed Effects:
            (Intr) timet1 prchrr
timet1      -0.087              
prochrrchcl -0.086  0.495       
tmt1:prchrr  0.061 -0.695 -0.699

Dimensionality reduction

Correlations between variables of same/different type/task

– Do DDM parameters capture similar processes as the raw measures in a given task or do they capture processes that are more similar across tasks? (If the former they would be less useful than if the latter.)

This could be analyzed with factor analysis but there are more variables than observations so as a first pass we’ll explore correlations.

if(!exists('all_data_cor')){
  source('/Users/zeynepenkavi/Dropbox/PoldrackLab/SRO_DDM_Analyses/code/workspace_scripts/var_cor_data.R')
}
fig_name = 'ddm_raw_vars_cor.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

(Absolute) correlations between raw and ddm measures within a task are higher than those between ddm measures across tasks. Note that only variables of same type are marked as ddm-ddm or raw-raw (e.g. a correlation between a threshold and another threshold is marked ddm-ddm while a correlation between a threshold and drift rate is not.).

Are the correlations between ddm parameters across tasks higher than correlations between ddm parameters and other variables from a given task? No. Correlations between variables of the same task are consistently higher.

In some sense that is good. We haven’t created all of these different tasks that putatively measure different things for nothing.

summary(lm(log(abs(value)) ~ ddm_ddm*task_task, all_data_cor))

Call:
lm(formula = log(abs(value)) ~ ddm_ddm * task_task, data = all_data_cor)

Residuals:
   Min     1Q Median     3Q    Max 
-9.118 -0.517  0.281  0.794  2.006 

Coefficients:
                                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)                        -2.1047     0.0138 -152.37  < 2e-16 ***
ddm_ddmraw-raw                     -0.2077     0.0196  -10.60  < 2e-16 ***
task_tasksame task                  1.1197     0.0439   25.51  < 2e-16 ***
ddm_ddmraw-raw:task_tasksame task  -0.3610     0.0650   -5.55  2.9e-08 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.11 on 14222 degrees of freedom
  (15784 observations deleted due to missingness)
Multiple R-squared:  0.071, Adjusted R-squared:  0.0708 
F-statistic:  362 on 3 and 14222 DF,  p-value: <2e-16

Factor analysis

Can we recover a 3 factor structure for DDM parameters that captures comparable processes across tasks?

Although the above correlation analyses suggest that variables from the same task are more similar compared to variables across tasks having even one measure per task is not very helpful with numerous tasks (in our case 14) particularly in terms of capturing cognitive mechanisms that are both common and distinct to these tasks.

Therefore we reduce the number of variables by running a factor analysis on a set of variables that ought to capture common processes across the tasks: the DDM parameters.

In another notebook I explore this more extensively and decide to use a 3 factor solution for the EZ variables. To summarize my conclusions:
- A 3 factor solution for the T1 EZ data is not necessarily the model with the lowest BIC but it is not significantly worse from a more complicated model with the lowest BIC.
- HDDM parameters don’t lend themselves as well to this analysis because the majority of the parameters are drift rates since only this parameter was allowed to vary across conditions. Therefore a 3 factor solution on the whole set of HDDM parameters mostly tries to separate out different drift rates from each other.
- Even when using a 3 factor solution the HDDM parameters don’t cluster as separably by parameter types as EZ parameters do.

Here is the depiction of the 3 factor solution for the EZ variables of T1 data.
Bars are colored by the variable type. Bars that are outlined in black load negatively on the factor they are in.

The figure suggests that the three parameter types are largely separable. The first factors captures a large majority of the drift rates. It, however, also contains numerous thresholds that load on negatively. The second factor in the middle contains mostly thresholds and the third factors contains only non-decision times.

fig_name = 'EZ_FA_T1_3.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

if(!exists('ez_t1_fa_3')){
  source('/Users/zeynepenkavi/Dropbox/PoldrackLab/SRO_DDM_Analyses/code/workspace_scripts/ez_fa_data.R')
}
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Dropping 0 variables with correlations above 0.85

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Using transformation:log
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
No positively skewed variables found.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
No negatively skewed variables found.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Dropping 0 variables with correlations above 0.85

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Using transformation:log
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
No positively skewed variables found.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
No negatively skewed variables found.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Dropping 0 variables with correlations above 0.85

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Using transformation:log
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
No positively skewed variables found.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
No negatively skewed variables found.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ez_t1_fa_3 = fa(res_clean_test_data_ez, 3, rotate='oblimin', fm='minres', scores='Anderson')
summary(ez_t1_fa_3)

Factor analysis with Call: fa(r = res_clean_test_data_ez, nfactors = 3, rotate = "oblimin", 
    scores = "Anderson", fm = "minres")

Test of the hypothesis that 3 factors are sufficient.
The degrees of freedom for the model is 21318  and the objective function was  469.9 
The number of observations was  150  with Chi Square =  35790  with prob <  0 

The root mean square of the residuals (RMSA) is  0.09 
The df corrected root mean square of the residuals is  0.09 

Tucker Lewis Index of factoring reliability =  0.858
RMSEA index =  0.124  and the 10 % confidence intervals are  0.066 NA
BIC =  -71027
 With factor correlations of 
      MR1   MR3   MR2
MR1  1.00 -0.20 -0.04
MR3 -0.20  1.00  0.18
MR2 -0.04  0.18  1.00

Reliability of lower dimensions

Are these clusters more reliable than using either the raw or the DDM measures alone?

I had some questions on how to calcualte reliabilities for latent variables. Details of my explorations on these questions can be found here:

I concluded to present two approaches to evaluate this:

  1. Predicting T2 using the 3 factor model from the T1 data
fig_name = 'ez_fa_rel_t2pred.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

  1. Fitting a 3 factor separately for the T2 data and comparing it to the T1 solution
fig_name = 'ez_fa_rel_t2fit.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

Here’s how the loadings the two models compare to each other

fig_name = 'ez_fa_t1vst2_loadings.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

Prediction

Do raw or DDM measures (or factor scores) predict real world outcomes better?

fig_name = 't1_pred.jpeg'

knitr::include_graphics(paste0(fig_path, fig_name))

LS0tCnRpdGxlOiAnU2VsZiBSZWd1bGF0aW9uIE9udG9sb2d5IERETSBBbmFseXNlcycKb3V0cHV0OgpnaXRodWJfZG9jdW1lbnQ6CnRvYzogeWVzCnRvY19mbG9hdDogeWVzCi0tLQoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CnNvdXJjZSgnL1VzZXJzL3pleW5lcGVua2F2aS9Ecm9wYm94L1BvbGRyYWNrTGFiL1NST19ERE1fQW5hbHlzZXMvY29kZS93b3Jrc3BhY2Vfc2NyaXB0cy9TUk9fRERNX0FuYWx5c2VzX1dvcmtzcGFjZS5SJykKYGBgCgpUaGUgdGFza3MgaW5jbHVkZWQgaW4gdGhpcyByZXBvcnQgYXJlOiAgCgpgYGB7cn0KdW5pcXVlKG1lYXN1cmVfbGFiZWxzJHRhc2tfZ3JvdXApCmBgYAoKT3VyIGFuYWx5c2VzIHNwYW4gYHIgbnJvdyhtZWFzdXJlX2xhYmVscylgIGRpZmZlcmVudCBtZWFzdXJlcy4KCipOT1RFOiogV2UgZm91bmQgdGhhdCBIRERNIHBhcmFtZXRlcnMgZm9yIFQxIGRhdGEgZG8gbm90IGRpZmZlciBpbiBhbnkgZGV0ZWN0YWJsZSB3YXkgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhleSBhcmUgZml0IHVzaW5nIHRoZSBmdWxsIFQxIHNhbXBsZSAobj01MjIpIG9yIG9ubHkgZm9yIHRoZSBzdWJzZXQgd2hvIGNvbXBsZXRlZCB0aGUgVDIgYmF0dGVyeSBhcyB3ZWxsIChuPTE1MCkuIFRoZXJlZm9yZSB0aGUgVDEgSERETSBwYXJhbWV0ZXJzIGluIHRoaXMgcmVwb3J0IGFyZSBiYXNlZCBvbiBmaXRzIGZyb20gbj0xNTAuIERldGFpbHMgb2YgdGhlc2UgYW5hbHlzZXMgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwczovL3plbmthdmkuZ2l0aHViLmlvL1NST19ERE1fQW5hbHlzZXMvb3V0cHV0L3JlcG9ydHMvSERETTE1MHZzNTIyLm5iLmh0bWwpLgoKYGBge3IgZWNobz1GQUxTRX0KI1dvcmtzcGFjZSBjbGVhbiB1cAp0b19yZW1vdmUgPSBjKCdyZWxfZGZfZnVsbGZpdCcsICdyZWxfZGZfcmVmaXQnLCAndGVzdF9kYXRhX2hkZG1fZnVsbGZpdCcsICd0ZXN0X2RhdGFfaGRkbV9yZWZpdCcsICdmdWxsZml0X2Jvb3RfZGYnLCAncmVmaXRfYm9vdF9kZicpCgpmb3IoaSBpbiAxOmxlbmd0aCh0b19yZW1vdmUpKXsKICBpZih0b19yZW1vdmVbaV0gJWluJSBscygpKXsKICAgIHJtKGxpc3Q9bHMoKVt3aGljaChscygpID09IHRvX3JlbW92ZVtpXSldKQogIH0KfQpgYGAKCiMjIERETSB2cyByYXcgcmVsaWFiaWxpdHkgb3ZlcmFsbAoKUGxvdCByZWxpYWJpbGl0eSBwb2ludCBlc3RpbWF0ZXMgY29tcGFyaW5nIERETSBtZWFzdXJlcyB0byByYXcgbWVhc3VyZXMgZmFjZXRpbmcgZm9yIGNvbnRyYXN0IG1lYXN1cmVzLgoKYGBge3J9CmZpZ19uYW1lID0gJ2RkbXZzcmF3X3BvaW50LmpwZWcnCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXN0ZTAoZmlnX3BhdGgsIGZpZ19uYW1lKSkKYGBgCgpQbG90IGF2ZXJhZ2VkIGJvb3RzdHJhcHBlZCByZWxpYWJpbGl0eSBlc3RpbWF0ZXMgcGVyIG1lYXN1cmUgY29tcGFyaW5nIERETSBtZWFzdXJlcyB0byByYXcgbWVhc3VyZXMgZmFjZXRpbmcgZm9yIGNvbnRyYXN0IG1lYXN1cmVzLgoKYGBge3J9CmZpZ19uYW1lID0gJ2RkbXZzcmF3X2Jvb3QuanBlZycKCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhc3RlMChmaWdfcGF0aCwgZmlnX25hbWUpKQpgYGAKCk1vZGVsIHRlc3RpbmcgaWYgdGhlIHJlbGlhYmlsaXR5IG9mIHJhdyBtZWFzdXJlcyBkaWZmZXJzIGZyb20gdGhhdCBvZiBkZG0gZXN0aW1hdGVzIGFuZCBpZiBjb250cmFzdCBtZWFzdXJlcyBkaWZmZXIgZnJvbSBub24tY29udHJhc3QgbWVhc3VyZXMuCgpDaGVja2luZyBpZiBib3RoIGZpeGVkIGVmZmVjdHMgb2YgcmF3IHZzIGRkbSBhbmQgY29udHJhc3QgdnMgbm9uLWNvbnRyYXN0IGFzIHdlbGwgYXMgdGhlaXIgaW50ZXJhY3Rpb24gaXMgbmVjZXNzYXJ5LgoKQ29uY2x1c2lvbjogSW50ZXJhY3RpdmUgbW9kZWwgaXMgYmVzdC4KCmBgYHtyfQptZXIxID0gbG1lcihpY2MyLjEgfiBkZG1fcmF3ICsgKDF8ZHYpLCBib290X2RmICU+JSBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpKQptZXIxYSA9IGxtZXIoaWNjMi4xIH4gb3ZlcmFsbF9kaWZmZXJlbmNlICsgKDF8ZHYpLCBib290X2RmICU+JSBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpKQptZXIyID0gbG1lcihpY2MyLjEgfiBkZG1fcmF3ICsgb3ZlcmFsbF9kaWZmZXJlbmNlICsgKDF8ZHYpLCBib290X2RmICU+JSBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpKQptZXIzID0gbG1lcihpY2MyLjEgfiBkZG1fcmF3ICogb3ZlcmFsbF9kaWZmZXJlbmNlICsgKDF8ZHYpLCBib290X2RmICU+JSBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpKQphbm92YShtZXIxLCBtZXIyLCBtZXIzKQphbm92YShtZXIxYSwgbWVyMiwgbWVyMykKYGBgCgpgYGB7cn0Kcm0obWVyMSwgbWVyMiwgbWVyMWEpCmBgYAoKUmF3IG1lYXN1cmVzIGRvIG5vdCBzaWduaWZpY2FudGx5IGRpZmZlciBmcm9tIGRkbSBwYXJhbWV0ZXJzIGluIHRoZWlyIHJlbGlhYmlsaXR5IGJ1dCBub24tY29udHJhc3QgbWVhc3VyZXMgYXJlIHNpZ25pZmljYW50bHkgbW9yZSByZWxpYWJsZSBjb21wYXJlZCB0byBjb250cmFzdCBhbmQgY29uZGl0aW9uIG1lYXN1cmVzLgoKYGBge3J9CnN1bW1hcnkobWVyMykKYGBgCgojIyMgQmVzdCBtZWFzdXJlIGZvciBlYWNoIHRhc2sKCldoYXQgaXMgdGhlIGJlc3QgbWVhc3VyZSBvZiBpbmRpdmlkdWFsIGRpZmZlcmVuY2UgZm9yIGFueSBtZWFzdXJlIHRoYXQgaGFzIGJvdGggcmF3IGFuZCBERE0gcGFyYW1ldGVycz8gCgpFdmVuIHRob3VnaCBvdmVyYWxsIHRoZSBkZG0gcGFyYW1ldGVycyBhcmUgbm90IHNpZ25pZmljYW50bHkgbGVzcyByZWxpYWJsZSB0aGUgbW9zdCByZWxpYWJsZSBtZWFzdXJlIGlzIG1vcmUgZnJlcXVlbnRseSBhIHJhdyBtZWFzdXJlLiBUaGVyZSBhcmUgc29tZSBleGFtcGxlcyBvZiBhbiBFWiBlc3RpbWF0ZSBiZWluZyB0aGUgYmVzdCBmb3IgYSB0YXNrIGFzIHdlbGwuIFJlZ2FyZGxlc3Mgb2YgcmF3IHZzIGRkbSB0aGUgYmVzdCBtZWFzdXJlIGlzIGFsd2F5cyBhIG5vbi1jb250cmFzdCBtZWFzdXJlLiAKCmBgYHtyfQpyZWxfZGYgJT4lCiAgZ3JvdXBfYnkodGFza19ncm91cCkgJT4lCiAgZmlsdGVyKGljYzIuMSA9PSBtYXgoaWNjMi4xKSkgJT4lCiAgc2VsZWN0KHRhc2tfZ3JvdXAsIGV2ZXJ5dGhpbmcoKSkKYGBgCgojIyMgVmFyaWFuY2UgYnJlYWtkb3duIG1lYXN1cmUgdHlwZXMKCmBgYHtyfQpmaWdfbmFtZSA9ICdkZG12c3Jhd192YXJzdWJzLmpwZWcnCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXN0ZTAoZmlnX3BhdGgsIGZpZ19uYW1lKSkKYGBgCgpgYGB7cn0KZmlnX25hbWUgPSAnZGRtdnNyYXdfdmFycmVzaWQuanBlZycKCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhc3RlMChmaWdfcGF0aCwgZmlnX25hbWUpKQpgYGAKCk1vZGVsIHRlc3RpbmcgaWYgdGhlIHBlcmNlbnRhZ2Ugb2YgYmV0d2VlbiBzdWJqZWN0cyB2YXJpYW5jZSBvZiByYXcgbWVhc3VyZXMgZGlmZmVycyBmcm9tIHRoYXQgb2YgZGRtIGVzdGltYXRlcyBhbmQgaWYgY29udHJhc3QgbWVhc3VyZXMgZGlmZmVyIGZyb20gbm9uLWNvbnRyYXN0IG1lYXN1cmVzLgoKQ2hlY2tpbmcgaWYgYm90aCBmaXhlZCBlZmZlY3RzIG9mIHJhdyB2cyBkZG0gYW5kIGNvbnRyYXN0IHZzIG5vbi1jb250cmFzdCBhcyB3ZWxsIGFzIHRoZWlyIGludGVyYWN0aW9uIGlzIG5lY2Vzc2FyeS4KCkNvbmNsdXNpb246IE1vZGVsIHdpdGggZml4ZWQgZWZmZWN0cyBmb3IgYm90aCBpcyBiZXN0LgoKYGBge3J9Cm1lcjEgPSBsbWVyKHZhcl9zdWJzX3BjdCB+IGRkbV9yYXcgKyAoMXxkdiksIGJvb3RfZGYgJT4lIGZpbHRlcihydF9hY2MgIT0gIm90aGVyIikpCm1lcjFhID0gbG1lcih2YXJfc3Vic19wY3QgfiBvdmVyYWxsX2RpZmZlcmVuY2UgKyAoMXxkdiksIGJvb3RfZGYgJT4lIGZpbHRlcihydF9hY2MgIT0gIm90aGVyIikpCm1lcjIgPSBsbWVyKHZhcl9zdWJzX3BjdCB+IGRkbV9yYXcgKyAgb3ZlcmFsbF9kaWZmZXJlbmNlICsgKDF8ZHYpLCBib290X2RmICU+JSBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpKQptZXIzID0gbG1lcih2YXJfc3Vic19wY3QgfiBkZG1fcmF3ICogIG92ZXJhbGxfZGlmZmVyZW5jZSArICgxfGR2KSwgYm9vdF9kZiAlPiUgZmlsdGVyKHJ0X2FjYyAhPSAib3RoZXIiKSkKYW5vdmEobWVyMSwgbWVyMiwgbWVyMykKYW5vdmEobWVyMWEsIG1lcjIsIG1lcjMpCmBgYAoKYGBge3J9CnJtKG1lcjEsIG1lcjFhLCBtZXIzKQpgYGAKCkNvbnRyYXN0IG1lYXN1cmVzIGhhdmUgbG93ZXIgYmV0d2VlbiBzdWJqZWN0cyB2YXJpYWJpbGl0eSAoaWUgYXJlIHdvcnNlIGluZGl2aWR1YWwgZGlmZmVyZW5jZSBtZWFzdXJlcykuIFJhdyBhbmQgZGRtIG1lYXN1cmVzIGRvIG5vdCBkaWZmZXIgc2lnbmlmaWNhbnRseS4KCmBgYHtyfQpzdW1tYXJ5KG1lcjIpCmBgYAoKTW9kZWwgdGVzdGluZyBpZiB0aGUgcGVyY2VudGFnZSBvZiByZXNpZHVhbCB2YXJpYW5jZSBvZiByYXcgbWVhc3VyZXMgZGlmZmVycyBmcm9tIHRoYXQgb2YgZGRtIGVzdGltYXRlcyBhbmQgaWYgY29udHJhc3QgbWVhc3VyZXMgZGlmZmVyIGZyb20gbm9uLWNvbnRyYXN0IG1lYXN1cmVzLgoKQ2hlY2tpbmcgaWYgYm90aCBmaXhlZCBlZmZlY3RzIG9mIHJhdyB2cyBkZG0gYW5kIGNvbnRyYXN0IHZzIG5vbi1jb250cmFzdCBhcyB3ZWxsIGFzIHRoZWlyIGludGVyYWN0aW9uIGlzIG5lY2Vzc2FyeS4KCkNvbmNsdXNpb246IEludGVyYWN0aXZlIG1vZGVsIGlzIGJlc3QKCmBgYHtyfQptZXIxID0gbG1lcih2YXJfcmVzaWRfcGN0IH4gZGRtX3JhdyArICgxfGR2KSwgYm9vdF9kZiAlPiUgZmlsdGVyKHJ0X2FjYyAhPSAib3RoZXIiKSkKbWVyMWEgPSBsbWVyKHZhcl9yZXNpZF9wY3QgfiBvdmVyYWxsX2RpZmZlcmVuY2UgKyAoMXxkdiksIGJvb3RfZGYgJT4lIGZpbHRlcihydF9hY2MgIT0gIm90aGVyIikpCm1lcjIgPSBsbWVyKHZhcl9yZXNpZF9wY3QgfiBkZG1fcmF3ICsgb3ZlcmFsbF9kaWZmZXJlbmNlICsgKDF8ZHYpLCBib290X2RmICU+JSBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpKQptZXIzID0gbG1lcih2YXJfcmVzaWRfcGN0IH4gZGRtX3JhdyAqIG92ZXJhbGxfZGlmZmVyZW5jZSArICgxfGR2KSwgYm9vdF9kZiAlPiUgZmlsdGVyKHJ0X2FjYyAhPSAib3RoZXIiKSkKYW5vdmEobWVyMSwgbWVyMiwgbWVyMykKYW5vdmEobWVyMWEsIG1lcjIsIG1lcjMpCmBgYAoKYGBge3J9CnJtKG1lcjEsIG1lcjFhLCBtZXIyKQpgYGAKCkJvdGggY29udHJhc3QgYW5kIGNvbmRpdGlvbiBtZWFzdXJlcyBoYXZlIGhpZ2hlciByZXNpZHVhbCB2YXJpYW5jZS4gUmF3IGFuZCBkZG0gbWVhc3VyZXMgZG8gbm90IGRpZmZlci4KCmBgYHtyfQpzdW1tYXJ5KG1lcjMpCmBgYAoKYGBge3J9CnJtKG1lcjMpCmBgYAoKRWZmZWN0cyBvZiBzYW1wbGUgc2l6ZSBvbiByZWxpYWJpbGl0eSBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vemVua2F2aS5naXRodWIuaW8vU1JPX0RETV9BbmFseXNlcy9vdXRwdXQvcmVwb3J0cy9TYW1wbGVTaXplRWZmZWN0c09uUmVsaWFiaWxpdHkubmIuaHRtbCkuCgojIyBIaWVyYXJjaGljYWwgZXN0aW1hdGlvbiBjb25zZXF1ZW5jZXMKClRoZSBIIGluIEhERE0gZXN0aW1hdGVzIHN0YW5kcyBmb3IgJ2hpZXJhcmNoaWNhbCcgZGVub3RpbmcgdGhlIGZhY3QgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSB3aG9sZSBzYW1wbGUgaXMgaW5jb3Jwb3J0YXRlZCBpbiB0aGUgcHJpb3JzIGZvciB0aGUgbW9kZWwgcGFyYW1ldGVycy4gVGhpcyBpcyBkaWZmZXJlbnQgdGhhbiBlLmcuIEVaLWRpZmZ1c2lvbiBwYXJhbWV0ZXJzIHRoYXQgd291bGQgYmUgdGhlIHNhbWUgZm9yIGEgZ2l2ZW4gc3ViamVjdCdzIGRhdGEgcmVnYXJkbGVzcyBvZiB0aGUgcmVzdCBvZiB0aGUgc2FtcGxlLiBPbmUgY2FuIGFzayB3aGV0aGVyIHRoaXMgSCBpbmRlZWQgaGFzIGEgbWVhc3VyYWJsZSBpbXBhY3QuCgpIRERNIGFuZCBFWiBwYXJhbWV0ZXIgZXN0aW1hdGVzIG1pZ2h0IGRpZmZlciBkdWUgdG8gb3RoZXIgZGlmZmVyZW5jZSBpbiB0aGUgZXN0aW1hdGlvbiBwcm9jZXNzIGFzIHdlbGwuIFRoZXJlZm9yZSB0byBldmFsdWF0ZSB3aGV0aGVyIHRoZSAnSCcgbGVhZHMgdG8gbWVhbmluZ2Z1bCBjaGFuZ2VzIGluIHBhcmFtZXRlcnMgd2UgY29tcGFyZSB0aGUgc2FtZSBtb2RlbHMgZml0IG9uIHRoZSBzYW1lIGRhdGEgdXNpbmcgZWl0aGVyIHRoZSB3aG9sZSBzYW1wbGUgZm9yIHRoZSBoaWVyYXJjaGljYWwgc3RydWN0dXJlIG9yIG9ubHkgdGhlIHNpbmdsZSBzdWJqZWN0J3MgZGF0YS4gVGhlc2UgbGF0dGVyIGVzdGltYXRlcyBhcmUgcmVmZXJyZWQgdG8gYXMgJ2ZsYXQnIGVzdGltYXRlcy4KCmBgYHtyfQpyZXRlc3RfaGRkbV9mbGF0ID0gcmVhZC5jc3YocGFzdGUwKHJldGVzdF9kYXRhX3BhdGgsJ3JldGVzdF9oZGRtX2ZsYXQuY3N2JykpCgpyZXRlc3RfaGRkbV9mbGF0ID0gcmV0ZXN0X2hkZG1fZmxhdCAlPiUgcmVuYW1lKHN1Yl9pZCA9IHN1YmpfaWQpCgp0ZXN0X2hkZG1fZmxhdCA9IHJlYWQuY3N2KHBhc3RlMChyZXRlc3RfZGF0YV9wYXRoLCcvdDFfZGF0YS90MV9oZGRtX2ZsYXQuY3N2JykpCgp0ZXN0X2hkZG1fZmxhdCA9IHRlc3RfaGRkbV9mbGF0ICU+JSByZW5hbWUoc3ViX2lkID0gc3Vial9pZCkKCiMgbnVtZXJpY19jb2xzID0gZ2V0X251bWVyaWNfY29scygpCgojIENoZWNrIGlmIGFsbCB0aGUgdmFyaWFibGVzIGFyZSB0aGVyZSAobm8gZm9yIG5vdykKIyBzdW0obmFtZXMocmV0ZXN0X2hkZG1fZmxhdCkgJWluJSBudW1lcmljX2NvbHMpID09IGxlbmd0aChuYW1lcyhyZXRlc3RfaGRkbV9mbGF0KSkKIyBuYW1lcyhyZXRlc3RfaGRkbV9mbGF0KVt3aGljaChuYW1lcyhyZXRlc3RfaGRkbV9mbGF0KSAlaW4lIG51bWVyaWNfY29scyA9PSBGQUxTRSldCgojIHN1bShuYW1lcyh0ZXN0X2hkZG1fZmxhdCkgJWluJSBudW1lcmljX2NvbHMpID09IGxlbmd0aChuYW1lcyh0ZXN0X2hkZG1fZmxhdCkpCiMgbmFtZXModGVzdF9oZGRtX2ZsYXQpW3doaWNoKG5hbWVzKHRlc3RfaGRkbV9mbGF0KSAlaW4lIG51bWVyaWNfY29scyA9PSBGQUxTRSldCmBgYAoKIyMjIFBhcmFtZXRlciB2YWx1ZQoKUGxvdCBwZXJjZW50IGNoYW5nZSBpbiByYXcgcGFyYW1ldGVycyBmb3IgcmV0ZXN0IGFuZCB0MSBmb3IgZWFjaCBvZiAzIHBhcmFtZXRlcnMgKHVzaW5nIGhpZXJhcmNoaWNhbCBhcyBiYXNlbGluZTogd2hhdCBwZXJjZW50IGRvZXMgdGhlIGZsYXQgcGFyYW1ldGVyIGNoYW5nZSBjb21wYXJlZCB0byB0aGUgaGllcmFyY2hpY2FsKQoKRm9yIGJvdGggdGltZSBwb2ludHMgdGhlIHRocmVzaG9sZHMgYW5kIG5vbi1kZWNpc2lvbiB0aW1lcyBhcmUgdmVyeSBzaW1pbGFyeSByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhleSBhcmUgZXN0aW1hdGVkIGhlaXJhcmNoaWNhbGx5IG9yIHdpdGhvdXQgdGhlIGhpZXJhcmNoeSAoZGlmZmVyZW5jZSBwZWFraW5nIGF0IDApLiAKClRoaXMgaXMgYWxzbyB0cnVlIGZvciB0aGUgbWFqb3JpdHkgb2YgdGhlIGRyaWZ0IHJhdGVzLiBUaGVyZSBhcmUsIGhvd2V2ZXIsIGFsbW9zdCBhcyBtYW55IGRyaWZ0IHJhdGVzIHRoYXQgY2hhbmdlIGNvbXBsZXRlbHkgd2hlbiBlc3RpbWF0ZWQgd2l0aG91dCB0aGUgaGllcmFyY2h5LiAgCgpgYGB7cn0KI1Nob3VsZCBub3QgYmUgbmVjZXNzYXJ5IGxhdGVyCmNvbW1vbl9jb2xzID0gbmFtZXMocmV0ZXN0X2hkZG1fZmxhdClbbmFtZXMocmV0ZXN0X2hkZG1fZmxhdCkgJWluJSBuYW1lcyhyZXRlc3RfZGF0YSldCmNvbW1vbl9jb2xzPWNvbW1vbl9jb2xzW2NvbW1vbl9jb2xzICVpbiUgbmFtZXModGVzdF9oZGRtX2ZsYXQpXQoKcmV0ZXN0X2hkZG1faGllciA9IHJldGVzdF9kYXRhICU+JSBzZWxlY3QoY29tbW9uX2NvbHMpICU+JSBtdXRhdGUoaGRkbT0iaGllcmFyY2hpY2FsIikKdGVzdF9oZGRtX2hpZXIgPSB0ZXN0X2RhdGEgJT4lIHNlbGVjdChjb21tb25fY29scykgICU+JSBtdXRhdGUoaGRkbT0iaGllcmFyY2hpY2FsIikKcmV0ZXN0X2hkZG1fZmxhdCA9IHJldGVzdF9oZGRtX2ZsYXQgJT4lIHNlbGVjdChjb21tb25fY29scykgJT4lIG11dGF0ZShoZGRtPSJmbGF0IikKdGVzdF9oZGRtX2ZsYXQgPSB0ZXN0X2hkZG1fZmxhdCAlPiUgc2VsZWN0KGNvbW1vbl9jb2xzKSAlPiUgbXV0YXRlKGhkZG09ImZsYXQiKQoKcmV0ZXN0X2ZsYXRfZGlmZmVyZW5jZSA9IHJiaW5kKHJldGVzdF9oZGRtX2hpZXIsIHJldGVzdF9oZGRtX2ZsYXQpCnJldGVzdF9mbGF0X2RpZmZlcmVuY2UgPSByZXRlc3RfZmxhdF9kaWZmZXJlbmNlICU+JQogIGdhdGhlcihkdiwgdmFsdWUsIC1zdWJfaWQsIC1oZGRtKSAlPiUKICBzcHJlYWQoaGRkbSwgdmFsdWUpICU+JQogIG11dGF0ZShkaWZmX3BjdCA9IChoaWVyYXJjaGljYWwgLSBmbGF0KS9oaWVyYXJjaGljYWwqMTAwLAogICAgICAgICBkaWZmX3BjdCA9IGlmZWxzZShkaWZmX3BjdDwoLTEwMCksIC0xMDAsIGlmZWxzZShkaWZmX3BjdD4xMDAsIDEwMCwgZGlmZl9wY3QpKSwKICAgICAgICAgdGltZSA9ICJyZXRlc3QiLAogICAgICAgICBwYXIgPSBpZmVsc2UoZ3JlcGwoImRyaWZ0IiwgZHYpLCAiZHJpZnQiLCBpZmVsc2UoZ3JlcGwoInRocmVzaCIsIGR2KSwgInRocmVzaCIsIGlmZWxzZShncmVwbCgibm9uX2RlY2lzaW9uIiwgZHYpLCAibm9uX2RlY2lzaW9uIiwgTkEpKSkpCgp0ZXN0X2ZsYXRfZGlmZmVyZW5jZSA9IHJiaW5kKHRlc3RfaGRkbV9oaWVyLCB0ZXN0X2hkZG1fZmxhdCkKdGVzdF9mbGF0X2RpZmZlcmVuY2UgPSB0ZXN0X2ZsYXRfZGlmZmVyZW5jZSAlPiUKICBnYXRoZXIoZHYsIHZhbHVlLCAtc3ViX2lkLCAtaGRkbSkgJT4lCiAgc3ByZWFkKGhkZG0sIHZhbHVlKSAlPiUKICBtdXRhdGUoZGlmZl9wY3QgPSAoaGllcmFyY2hpY2FsIC0gZmxhdCkvaGllcmFyY2hpY2FsKjEwMCwKICAgICAgICAgZGlmZl9wY3QgPSBpZmVsc2UoZGlmZl9wY3Q8KC0xMDApLCAtMTAwLCBpZmVsc2UoZGlmZl9wY3Q+MTAwLCAxMDAsIGRpZmZfcGN0KSksCiAgICAgICAgIHRpbWUgPSAidGVzdCIsCiAgICAgICAgIHBhciA9IGlmZWxzZShncmVwbCgiZHJpZnQiLCBkdiksICJkcmlmdCIsIGlmZWxzZShncmVwbCgidGhyZXNoIiwgZHYpLCAidGhyZXNoIiwgaWZlbHNlKGdyZXBsKCJub25fZGVjaXNpb24iLCBkdiksICJub25fZGVjaXNpb24iLCBOQSkpKSkKCmZsYXRfZGlmZmVyZW5jZSA9IHJiaW5kKHRlc3RfZmxhdF9kaWZmZXJlbmNlLCByZXRlc3RfZmxhdF9kaWZmZXJlbmNlKQpgYGAKCgpgYGB7cn0KZmxhdF9kaWZmZXJlbmNlICU+JQogIGdncGxvdChhZXMoZGlmZl9wY3QpKSsKICBnZW9tX2hpc3RvZ3JhbSgpKwogIGZhY2V0X2dyaWQoZmFjdG9yKHRpbWUsIGxldmVscyA9IGMoInRlc3QiLCAicmV0ZXN0IiksbGFiZWxzID0gYygidGVzdCIsICJyZXRlc3QiKSkgfiBwYXIsIHNjYWxlcz0iZnJlZSIpKwogIHhsYWIoIlBlcmNlbnQgY2hhbmdlIikKYGBgCgpJcyB0aGUgYXZlcmFnZSBwZXJjZW50YWdlIGNoYW5nZSBkaWZmZXJlbnQgdGhhbiAwPyBOby4KClRoaXMgbW9kZWwgdXNlcyB0aGUgZGlzdHJpYnV0aW9uIG9mIHBlcmNlbnRhZ2UgZGlmZmVyZW5jZSBpbiBwYXJhbWV0ZXIgZXN0aW1hdGVzIGZvciBkcmlmdCByYXRlcyBhcyB0aGUgYmFzZWxpbmUuIEEgbW9yZSBhcHByb3ByaWF0ZSBtb2RlbCB3b3VsZCB0ZXN0IHdoZXRoZXIgYWxsIHRocmVlIGRpc3RyaWJ1dGlvbnMgYXJlIGRpZmZlcmVudCB0aGFuIDAuIFRoZSBjb25jbHVzaW9uIHNob3VsZCBub3QgY2hhbmdlOiBUaGUgaW50ZXJjZXB0IHN1Z2dlc3RzIHRoYXQgdGhlIG1lYW4gb2YgdGhlIGRyaWZ0IHJhdGUgZGlmZmVyZW5jZSBkaXN0cmlidXRpb24gaXMgYXQgMCBhbmQgdGhpcyBpcyBub3QgZGlmZmVyZW50IHRoYW4gdGhlIGRpc3RyaWJ1dGlvbnMgZm9yIGVpdGhlciBvZiB0aGUgb3RoZXIgcGFyYW1ldGVycyBhbmQgZWl0aGVyIHRpbWUgcG9pbnQuCgpgYGB7cn0Kc3VtbWFyeShsbWVyKGRpZmZfcGN0IH4gdGltZSpwYXIrKDF8ZHYpLCBmbGF0X2RpZmZlcmVuY2UgJT4lIG11dGF0ZShwYXJzID0gZmFjdG9yKHBhciwgbGV2ZWxzID0gYygidGhyZXNoIiwgImRyaWZ0IiwgIm5vbl9kZWNpc2lvbiIpKSkpKQpgYGAKCkRvIHBlb3BsZSBjaGFuZ2UgaW4gdGhlIHNhbWUgd2F5PyBNb3N0bHkuCgpQbG90dGluZyB0aGUgcmF3IHBhcmFtZXRlciBlc3RpbWF0ZSB0aGF0IGlzIGVzdGltYXRlZCBoaWVyYXJjaGljYWxseSBhZ2FpbnN0IHRoZSBlc3RpbWF0ZSB0aGF0IGlzIGVzdGltYXRlZCB3aXRob3V0IHRoZSBoaWVyYXJjaHkuIFJlZCBsaW5lcyBhcmUgdGhlIDQ1LWRlZ3JlZSBsaW5lLiBUaGUgZmFjdCB0aGF0IG1hbnkgcG9pbnRzIGNsdXN0ZXIgYXJvdW5kIHRoaXMgbGluZSBhbmQgdGhhdCB0aGVyZSBhcmUgbm8gc3lzdGVtYXRpYyBkZXZpYW5jZXMgZnJvbSBpdCBmb3IgYW55IHBhcmFtZXRlciBhdCBlaXRoZXIgdGltZSBwb2ludCBzdWdnZXN0cyB0aGF0IHRoZSBoaWVyYXJjaGljYWwgYW5kIGZsYXQgZXN0aW1hdGVzIGFyZSBtb3N0bHkgdGhlIHNhbWUuCgpgYGB7cn0KZmlnX25hbWUgPSAnSERETV9wYXJfZmxhdHZzaGllci5qcGVnJwoKa25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGFzdGUwKGZpZ19wYXRoLCBmaWdfbmFtZSkpCmBgYAoKIyMjIFBhcmFtZXRlciByZWxpYWJpbGl0eQoKUGxvdHRpbmcgdGhlIHJlbGlhYmlsaXR5IGVzdGltYXRlcyBmb3IgZmxhdCBwYXJhbWV0ZXJzIGFnYWluc3QgdGhlIHJlbGlhYmlsaXR5IG9mIGhpZXJhcmNoaWNhbCBlc3RpbWF0ZXMuIFJlZCBsaW5lcyBhcmUgNDUtZGVncmVlIGxpbmVzLiBXaGlsZSB0aGVyZSBhcmUgc29tZSBjaGFuZ2VzIGluIHJlbGlhYmlsaXR5IG5vdGhpbmcgYXBwZWFycyB2ZXJ5IGxhcmdlIChvciBjb25zZXF1ZW50aWFsIGluIHB1c2hpbmcgdGhlIHJlbGlhYmlsaXR5IHRvIGFueSBhY2NlcHRhYmxlIGxldmVsIGRlcGVuZGluZyBvbiB0aGUgZXN0aW1hdGlvbiBtZXRob2QpIG9yIHN5c3RlbWF0aWMuCgpgYGB7cn0KcmVsX2RmX2ZsYXQgPSBtYWtlX3JlbF9kZih0MV9kZiA9IHRlc3RfaGRkbV9mbGF0LCB0Ml9kZiA9IHJldGVzdF9oZGRtX2ZsYXQsIG1ldHJpY3MgPSBjKCdpY2MyLjEnLCAncGVhcnNvbicsICd2YXJfYnJlYWtkb3duJykpCgpyZWxfZGZfZmxhdCA9IHJlbF9kZl9mbGF0ICU+JQogIGxlZnRfam9pbihyZWxfZGZbLGMoImR2IiwgImljYzIuMSIsICJydF9hY2MiLCAib3ZlcmFsbF9kaWZmZXJlbmNlIildLCBieSA9ICJkdiIpIApgYGAKCmBgYHtyfQpmaWdfbmFtZSA9ICdIRERNX3JlbF9mbGF0dnNoaWVyLmpwZWcnCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXN0ZTAoZmlnX3BhdGgsIGZpZ19uYW1lKSkKYGBgCgpgYGB7cn0Kd2l0aChyZWxfZGZfZmxhdCAlPiUgZmlsdGVyKHJ0X2FjYyA9PSAiZHJpZnQgcmF0ZSIpLCB0LnRlc3QoaWNjMi4xLngsIGljYzIuMS55LCBwYWlyZWQ9VCkpCndpdGgocmVsX2RmX2ZsYXQgJT4lIGZpbHRlcihydF9hY2MgPT0gInRocmVzaG9sZCIpLCB0LnRlc3QoaWNjMi4xLngsIGljYzIuMS55LCBwYWlyZWQ9VCkpCndpdGgocmVsX2RmX2ZsYXQgJT4lIGZpbHRlcihydF9hY2MgPT0gIm5vbi1kZWNpc2lvbiIpLCB0LnRlc3QoaWNjMi4xLngsIGljYzIuMS55LCBwYWlyZWQ9VCkpCmBgYAoKYGBge3J9CnJtKGZsYXRfZGlmZmVyZW5jZSwgcmVsX2RmX2ZsYXQsIHJldGVzdF9mbGF0X2RpZmZlcmVuY2UsIHJldGVzdF9oZGRtX2ZsYXQsIHJldGVzdF9oZGRtX2hpZXIsIHRlc3RfZmxhdF9kaWZmZXJlbmNlLCAgdGVzdF9oZGRtX2ZsYXQsIHRlc3RfaGRkbV9oaWVyKQpgYGAKCiMjIyBQYXJhbWV0ZXIgZml0CgpEbyB0aGUgZml0IHN0YXRpc3RpY3MgZGlmZmVyIGJ5IHdoZXRoZXIgdGhlIG1vZGVsIHdhcyBoaWVyYXJjaGljYWwgb3Igbm90PyBOby4KCmBgYHtyfQp0MV9oaWVyYXJjaGljYWxfZml0c3RhdHMgPSB0MV9oaWVyYXJjaGljYWxfZml0c3RhdHMgJT4lCiAgZmlsdGVyKHN1YmpfaWQgJWluJSByZXRlc3RfaGllcmFyY2hpY2FsX2ZpdHN0YXRzJHN1YmpfaWQpCgp0bXAgPSByYmluZChyZXRlc3RfaGllcmFyY2hpY2FsX2ZpdHN0YXRzLCByZXRlc3RfZmxhdF9maXRzdGF0cywgdDFfaGllcmFyY2hpY2FsX2ZpdHN0YXRzLCB0MV9mbGF0X2ZpdHN0YXRzKSAlPiUKICBzZWxlY3QobV9rbCwgc3Vial9pZCwgdGFza19uYW1lLCBzYW1wbGUpICU+JQogIHNlcGFyYXRlKHNhbXBsZSwgYygidGltZSIsICJwcm9jIiksIHNlcD0iXyIsIHJlbW92ZT1GQUxTRSkKICAKYGBgCgpgYGB7cn0KZmlnX25hbWUgPSAnSERETV9maXRzdGF0c19mbGF0dnNoaWVyLmpwZWcnCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXN0ZTAoZmlnX3BhdGgsIGZpZ19uYW1lKSkKYGBgCgpgYGB7cn0KdG1wCnN1bW1hcnkobG1lcihtX2tsIH4gdGltZSpwcm9jKygxfHRhc2tfbmFtZSksdG1wKSkKYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQpybShyZWZpdF9maXRzdGF0cywgcmV0ZXN0X2ZsYXRfZml0c3RhdHMsIHJldGVzdF9oaWVyYXJjaGljYWxfZml0c3RhdHMsIHQxX2ZsYXRfZml0c3RhdHMsIHQxX2hpZXJhcmNoaWNhbF9maXRzdGF0cywgdG1wKQpgYGAKCiMjIERpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbgoKIyMjIENvcnJlbGF0aW9ucyBiZXR3ZWVuIHZhcmlhYmxlcyBvZiBzYW1lL2RpZmZlcmVudCB0eXBlL3Rhc2sKCi0tIERvIERETSBwYXJhbWV0ZXJzIGNhcHR1cmUgc2ltaWxhciBwcm9jZXNzZXMgYXMgdGhlIHJhdyBtZWFzdXJlcyBpbiBhIGdpdmVuIHRhc2sgb3IgZG8gdGhleSBjYXB0dXJlIHByb2Nlc3NlcyB0aGF0IGFyZSBtb3JlIHNpbWlsYXIgYWNyb3NzIHRhc2tzPwooSWYgdGhlIGZvcm1lciB0aGV5IHdvdWxkIGJlIGxlc3MgdXNlZnVsIHRoYW4gaWYgdGhlIGxhdHRlci4pICAKClRoaXMgY291bGQgYmUgYW5hbHl6ZWQgd2l0aCBmYWN0b3IgYW5hbHlzaXMgYnV0IHRoZXJlIGFyZSBtb3JlIHZhcmlhYmxlcyB0aGFuIG9ic2VydmF0aW9ucyBzbyBhcyBhIGZpcnN0IHBhc3Mgd2UnbGwgZXhwbG9yZSBjb3JyZWxhdGlvbnMuICAgIAoKYGBge3J9CmlmKCFleGlzdHMoJ2FsbF9kYXRhX2NvcicpKXsKICBzb3VyY2UoJy9Vc2Vycy96ZXluZXBlbmthdmkvRHJvcGJveC9Qb2xkcmFja0xhYi9TUk9fRERNX0FuYWx5c2VzL2NvZGUvd29ya3NwYWNlX3NjcmlwdHMvdmFyX2Nvcl9kYXRhLlInKQp9CmBgYAoKYGBge3J9CmZpZ19uYW1lID0gJ2RkbV9yYXdfdmFyc19jb3IuanBlZycKCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhc3RlMChmaWdfcGF0aCwgZmlnX25hbWUpKQpgYGAKCihBYnNvbHV0ZSkgY29ycmVsYXRpb25zIGJldHdlZW4gcmF3IGFuZCBkZG0gbWVhc3VyZXMgd2l0aGluIGEgdGFzayBhcmUgaGlnaGVyIHRoYW4gdGhvc2UgYmV0d2VlbiBkZG0gbWVhc3VyZXMgYWNyb3NzIHRhc2tzLiBOb3RlIHRoYXQgb25seSB2YXJpYWJsZXMgb2Ygc2FtZSB0eXBlIGFyZSBtYXJrZWQgYXMgZGRtLWRkbSBvciByYXctcmF3IChlLmcuIGEgY29ycmVsYXRpb24gYmV0d2VlbiBhIHRocmVzaG9sZCBhbmQgYW5vdGhlciB0aHJlc2hvbGQgaXMgbWFya2VkIGRkbS1kZG0gd2hpbGUgYSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGEgdGhyZXNob2xkIGFuZCBkcmlmdCByYXRlIGlzIG5vdC4pLgoKYGBge3IgIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9CmFsbF9kYXRhX2Nvcl9tZWQKYGBgCgpBcmUgdGhlIGNvcnJlbGF0aW9ucyBiZXR3ZWVuIGRkbSBwYXJhbWV0ZXJzIGFjcm9zcyB0YXNrcyBoaWdoZXIgdGhhbiBjb3JyZWxhdGlvbnMgYmV0d2VlbiBkZG0gcGFyYW1ldGVycyBhbmQgb3RoZXIgdmFyaWFibGVzIGZyb20gYSBnaXZlbiB0YXNrPwpOby4gQ29ycmVsYXRpb25zIGJldHdlZW4gdmFyaWFibGVzIG9mIHRoZSBzYW1lIHRhc2sgYXJlIGNvbnNpc3RlbnRseSBoaWdoZXIuCgpJbiBzb21lIHNlbnNlIHRoYXQgaXMgZ29vZC4gV2UgaGF2ZW4ndCBjcmVhdGVkIGFsbCBvZiB0aGVzZSBkaWZmZXJlbnQgdGFza3MgdGhhdCBwdXRhdGl2ZWx5IG1lYXN1cmUgZGlmZmVyZW50IHRoaW5ncyBmb3Igbm90aGluZy4KCmBgYHtyfQpzdW1tYXJ5KGxtKGxvZyhhYnModmFsdWUpKSB+IGRkbV9kZG0qdGFza190YXNrLCBhbGxfZGF0YV9jb3IpKQpgYGAKCmBgYHtyICBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQpybShhbGxfZGF0YV9jb3IsIGFsbF9kYXRhX2Nvcl9tZWQpCmBgYAoKIyMjIEZhY3RvciBhbmFseXNpcwoKQ2FuIHdlIHJlY292ZXIgYSAzIGZhY3RvciBzdHJ1Y3R1cmUgZm9yIERETSBwYXJhbWV0ZXJzIHRoYXQgY2FwdHVyZXMgY29tcGFyYWJsZSBwcm9jZXNzZXMgYWNyb3NzIHRhc2tzPyAgIAoKQWx0aG91Z2ggdGhlIGFib3ZlIGNvcnJlbGF0aW9uIGFuYWx5c2VzIHN1Z2dlc3QgdGhhdCB2YXJpYWJsZXMgZnJvbSB0aGUgc2FtZSB0YXNrIGFyZSBtb3JlIHNpbWlsYXIgY29tcGFyZWQgdG8gdmFyaWFibGVzIGFjcm9zcyB0YXNrcyBoYXZpbmcgZXZlbiBvbmUgbWVhc3VyZSBwZXIgdGFzayBpcyBub3QgdmVyeSBoZWxwZnVsIHdpdGggbnVtZXJvdXMgdGFza3MgKGluIG91ciBjYXNlIDE0KSBwYXJ0aWN1bGFybHkgaW4gdGVybXMgb2YgY2FwdHVyaW5nIGNvZ25pdGl2ZSBtZWNoYW5pc21zIHRoYXQgYXJlIGJvdGggY29tbW9uIGFuZCBkaXN0aW5jdCB0byB0aGVzZSB0YXNrcy4gIAoKVGhlcmVmb3JlIHdlIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHZhcmlhYmxlcyBieSBydW5uaW5nIGEgZmFjdG9yIGFuYWx5c2lzIG9uIGEgc2V0IG9mIHZhcmlhYmxlcyB0aGF0IG91Z2h0IHRvIGNhcHR1cmUgY29tbW9uIHByb2Nlc3NlcyBhY3Jvc3MgdGhlIHRhc2tzOiB0aGUgRERNIHBhcmFtZXRlcnMuICAKCltJbiBhbm90aGVyIG5vdGVib29rXShodHRwczovL3plbmthdmkuZ2l0aHViLmlvL1NST19ERE1fQW5hbHlzZXMvb3V0cHV0L3JlcG9ydHMvRGltUmVkdWN0aW9uQ29tcGFyaXNvbi5uYi5odG1sKSBJIGV4cGxvcmUgdGhpcyBtb3JlIGV4dGVuc2l2ZWx5IGFuZCBkZWNpZGUgdG8gdXNlIGEgMyBmYWN0b3Igc29sdXRpb24gZm9yIHRoZSBFWiB2YXJpYWJsZXMuICBUbyBzdW1tYXJpemUgbXkgY29uY2x1c2lvbnM6ICAgCi0gQSAzIGZhY3RvciBzb2x1dGlvbiBmb3IgdGhlIFQxIEVaIGRhdGEgaXMgbm90IG5lY2Vzc2FyaWx5IHRoZSBtb2RlbCB3aXRoIHRoZSBsb3dlc3QgQklDIGJ1dCBpdCBpcyBub3Qgc2lnbmlmaWNhbnRseSB3b3JzZSBmcm9tIGEgbW9yZSBjb21wbGljYXRlZCBtb2RlbCB3aXRoIHRoZSBsb3dlc3QgQklDLiAgCi0gSERETSBwYXJhbWV0ZXJzIGRvbid0IGxlbmQgdGhlbXNlbHZlcyBhcyB3ZWxsIHRvIHRoaXMgYW5hbHlzaXMgYmVjYXVzZSB0aGUgbWFqb3JpdHkgb2YgdGhlIHBhcmFtZXRlcnMgYXJlIGRyaWZ0IHJhdGVzIHNpbmNlIG9ubHkgdGhpcyBwYXJhbWV0ZXIgd2FzIGFsbG93ZWQgdG8gdmFyeSBhY3Jvc3MgY29uZGl0aW9ucy4gVGhlcmVmb3JlIGEgMyBmYWN0b3Igc29sdXRpb24gb24gdGhlIHdob2xlIHNldCBvZiBIRERNIHBhcmFtZXRlcnMgbW9zdGx5IHRyaWVzIHRvIHNlcGFyYXRlIG91dCBkaWZmZXJlbnQgZHJpZnQgcmF0ZXMgZnJvbSBlYWNoIG90aGVyLiAgICAKLSBFdmVuIHdoZW4gdXNpbmcgYSAzIGZhY3RvciBzb2x1dGlvbiB0aGUgSERETSBwYXJhbWV0ZXJzIGRvbid0IGNsdXN0ZXIgYXMgc2VwYXJhYmx5IGJ5IHBhcmFtZXRlciB0eXBlcyBhcyBFWiBwYXJhbWV0ZXJzIGRvLiAgCgpIZXJlIGlzIHRoZSBkZXBpY3Rpb24gb2YgdGhlIDMgZmFjdG9yIHNvbHV0aW9uIGZvciB0aGUgRVogdmFyaWFibGVzIG9mIFQxIGRhdGEuICAKQmFycyBhcmUgY29sb3JlZCBieSB0aGUgdmFyaWFibGUgdHlwZS4gQmFycyB0aGF0IGFyZSBvdXRsaW5lZCBpbiBibGFjayBsb2FkIG5lZ2F0aXZlbHkgb24gdGhlIGZhY3RvciB0aGV5IGFyZSBpbi4KClRoZSBmaWd1cmUgc3VnZ2VzdHMgdGhhdCB0aGUgdGhyZWUgcGFyYW1ldGVyIHR5cGVzIGFyZSBsYXJnZWx5IHNlcGFyYWJsZS4gVGhlIGZpcnN0IGZhY3RvcnMgY2FwdHVyZXMgYSBsYXJnZSBtYWpvcml0eSBvZiB0aGUgZHJpZnQgcmF0ZXMuIEl0LCBob3dldmVyLCBhbHNvIGNvbnRhaW5zIG51bWVyb3VzIHRocmVzaG9sZHMgdGhhdCBsb2FkIG9uIG5lZ2F0aXZlbHkuIFRoZSBzZWNvbmQgZmFjdG9yIGluIHRoZSBtaWRkbGUgY29udGFpbnMgbW9zdGx5IHRocmVzaG9sZHMgYW5kIHRoZSB0aGlyZCBmYWN0b3JzIGNvbnRhaW5zIG9ubHkgbm9uLWRlY2lzaW9uIHRpbWVzLgoKYGBge3J9CmZpZ19uYW1lID0gJ0VaX0ZBX1QxXzMuanBlZycKCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhc3RlMChmaWdfcGF0aCwgZmlnX25hbWUpKQpgYGAKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmlmKCFleGlzdHMoJ2V6X3QxX2ZhXzMnKSl7CiAgc291cmNlKCcvVXNlcnMvemV5bmVwZW5rYXZpL0Ryb3Bib3gvUG9sZHJhY2tMYWIvU1JPX0RETV9BbmFseXNlcy9jb2RlL3dvcmtzcGFjZV9zY3JpcHRzL2V6X2ZhX2RhdGEuUicpCn0KCmV6X3QxX2ZhXzMgPSBmYShyZXNfY2xlYW5fdGVzdF9kYXRhX2V6LCAzLCByb3RhdGU9J29ibGltaW4nLCBmbT0nbWlucmVzJywgc2NvcmVzPSdBbmRlcnNvbicpCnN1bW1hcnkoZXpfdDFfZmFfMykKYGBgCgojIyMgUmVsaWFiaWxpdHkgb2YgbG93ZXIgZGltZW5zaW9ucwoKQXJlIHRoZXNlIGNsdXN0ZXJzIG1vcmUgcmVsaWFibGUgdGhhbiB1c2luZyBlaXRoZXIgdGhlIHJhdyBvciB0aGUgRERNIG1lYXN1cmVzIGFsb25lPwoKSSBoYWQgc29tZSBxdWVzdGlvbnMgb24gaG93IHRvIGNhbGN1YWx0ZSByZWxpYWJpbGl0aWVzIGZvciBsYXRlbnQgdmFyaWFibGVzLiBEZXRhaWxzIG9mIG15IGV4cGxvcmF0aW9ucyBvbiB0aGVzZSBxdWVzdGlvbnMgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwczovL3plbmthdmkuZ2l0aHViLmlvL1NST19ERE1fQW5hbHlzZXMvb3V0cHV0L3JlcG9ydHMvTGF0ZW50VmFyaWFibGVSZWxpYWJpbGl0eS5uYi5odG1sKToKCkkgY29uY2x1ZGVkIHRvIHByZXNlbnQgdHdvIGFwcHJvYWNoZXMgdG8gZXZhbHVhdGUgdGhpczoKCjEuIFByZWRpY3RpbmcgVDIgdXNpbmcgdGhlIDMgZmFjdG9yIG1vZGVsIGZyb20gdGhlIFQxIGRhdGEKCmBgYHtyfQpmaWdfbmFtZSA9ICdlel9mYV9yZWxfdDJwcmVkLmpwZWcnCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXN0ZTAoZmlnX3BhdGgsIGZpZ19uYW1lKSkKYGBgCgoyLiBGaXR0aW5nIGEgMyBmYWN0b3Igc2VwYXJhdGVseSBmb3IgdGhlIFQyIGRhdGEgYW5kIGNvbXBhcmluZyBpdCB0byB0aGUgVDEgc29sdXRpb24KCmBgYHtyfQpmaWdfbmFtZSA9ICdlel9mYV9yZWxfdDJmaXQuanBlZycKCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhc3RlMChmaWdfcGF0aCwgZmlnX25hbWUpKQpgYGAKCkhlcmUncyBob3cgdGhlIGxvYWRpbmdzIHRoZSB0d28gbW9kZWxzIGNvbXBhcmUgdG8gZWFjaCBvdGhlcgoKYGBge3J9CmZpZ19uYW1lID0gJ2V6X2ZhX3QxdnN0Ml9sb2FkaW5ncy5qcGVnJwoKa25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGFzdGUwKGZpZ19wYXRoLCBmaWdfbmFtZSkpCmBgYAoKIyMgUHJlZGljdGlvbgoKRG8gcmF3IG9yIERETSBtZWFzdXJlcyAob3IgZmFjdG9yIHNjb3JlcykgcHJlZGljdCByZWFsIHdvcmxkIG91dGNvbWVzIGJldHRlcj8KCmBgYHtyfQpmaWdfbmFtZSA9ICd0MV9wcmVkLmpwZWcnCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXN0ZTAoZmlnX3BhdGgsIGZpZ19uYW1lKSkKYGBg